SVM patch to fix problem with evtchn/lost interrupts and re-enable hvm_safe_block().
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 22 Mar 2006 09:36:02 +0000 (10:36 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 22 Mar 2006 09:36:02 +0000 (10:36 +0100)
Signed-off-by: Tom Woller <thomas.woller@amd.com>
xen/arch/x86/hvm/svm/intr.c
xen/arch/x86/hvm/svm/svm.c

index 430cad9372499103ceae8ee9b380dfff3874035e..86fc6e4b9d1050b557d0b78373af680a3fd3a245 100644 (file)
@@ -58,6 +58,7 @@ static inline int svm_inject_extint(struct vcpu *v, int trap, int error_code)
     intr.fields.intr_masking = 1;
     intr.fields.vector = trap;
     intr.fields.prio = 0xF;
+    intr.fields.ign_tpr = 1;
     vmcb->vintr = intr;
 //  printf( "IRQ = %d\n", trap );
     return 0;
@@ -160,18 +161,21 @@ asmlinkage void svm_intr_assist(void)
     }
     /* Now let's check for newer interrrupts  */
     else {
-        /* Interrput pending at the PIC? */
-        hvm_pic_assist(v);
 
-        if (vpit->pending_intr_nr) {
-            pic_set_irq(pic, 0, 0);
-            pic_set_irq(pic, 0, 1);
-        }
-
-        if (plat->interrupt_request) {
-            intr_vector = cpu_get_interrupt(v, &intr_type);
-            plat->interrupt_request = 0;
-        }
+      if ( v->vcpu_id == 0 )
+         hvm_pic_assist(v);
+
+      /* Before we deal with PIT interrupts, let's check
+         for interrupts set by the device model.
+      */
+      if ( cpu_has_pending_irq(v) ) {
+           intr_vector = cpu_get_interrupt(v, &intr_type);
+      }
+      else  if ( (v->vcpu_id == 0) && vpit->pending_intr_nr ) {
+          pic_set_irq(pic, 0, 0);
+          pic_set_irq(pic, 0, 1);
+          intr_vector = cpu_get_interrupt(v, &intr_type);
+      }
     }
 
     /* have we got an interrupt to inject? */
index d3fa01177315f3cdee2e4bc342694bc24b10d8ab..a19468a9a049ccc5a5467787daf627d0dc923a47 100644 (file)
@@ -1777,6 +1777,10 @@ static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
 
     __update_guest_eip(vmcb, 1);
 
+    /* check for interrupt not handled or new interrupt */
+    if ( vmcb->vintr.fields.irq || cpu_has_pending_irq(v) )
+       return; 
+
     if ( !v->vcpu_id )
         next_pit = get_pit_scheduled(v, vpit);
     next_wakeup = get_apictime_scheduled(v);
@@ -1784,9 +1788,7 @@ static inline void svm_vmexit_do_hlt(struct vmcb_struct *vmcb)
         next_wakeup = next_pit;
     if ( next_wakeup != - 1 )
         set_timer(&current->arch.hvm_svm.hlt_timer, next_wakeup);
-/* temporary workaround for 8828/8822 evtchn patches causing SVM failure.
     hvm_safe_block();
-*/
 }